2008-08-31 22:13:54 +07:00
|
|
|
#ifndef _LINUX_STRING_HELPERS_H_
|
|
|
|
#define _LINUX_STRING_HELPERS_H_
|
|
|
|
|
|
|
|
#include <linux/types.h>
|
|
|
|
|
|
|
|
/* Descriptions of the types of units to
|
|
|
|
* print in */
|
|
|
|
enum string_size_units {
|
|
|
|
STRING_UNITS_10, /* use powers of 10^3 (standard SI) */
|
|
|
|
STRING_UNITS_2, /* use binary powers of 2^10 */
|
|
|
|
};
|
|
|
|
|
sd, mmc, virtio_blk, string_helpers: fix block size units
The current string_get_size() overflows when the device size goes over
2^64 bytes because the string helper routine computes the suffix from
the size in bytes. However, the entirety of Linux thinks in terms of
blocks, not bytes, so this will artificially induce an overflow on very
large devices. Fix this by making the function string_get_size() take
blocks and the block size instead of bytes. This should allow us to
keep working until the current SCSI standard overflows.
Also fix virtio_blk and mmc (both of which were also artificially
multiplying by the block size to pass a byte side to string_get_size()).
The mathematics of this is pretty simple: we're taking a product of
size in blocks (S) and block size (B) and trying to re-express this in
exponential form: S*B = R*N^E (where N, the exponent is either 1000 or
1024) and R < N. Mathematically, S = RS*N^ES and B=RB*N^EB, so if RS*RB
< N it's easy to see that S*B = RS*RB*N^(ES+EB). However, if RS*BS > N,
we can see that this can be re-expressed as RS*BS = R*N (where R =
RS*BS/N < N) so the whole exponent becomes R*N^(ES+EB+1)
[jejb: fix incorrect 32 bit do_div spotted by kbuild test robot <fengguang.wu@intel.com>]
Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: James Bottomley <JBottomley@Odin.com>
2015-03-06 09:47:01 +07:00
|
|
|
void string_get_size(u64 size, u64 blk_size, enum string_size_units units,
|
2015-02-13 06:01:50 +07:00
|
|
|
char *buf, int len);
|
2008-08-31 22:13:54 +07:00
|
|
|
|
2013-05-01 05:27:30 +07:00
|
|
|
#define UNESCAPE_SPACE 0x01
|
|
|
|
#define UNESCAPE_OCTAL 0x02
|
|
|
|
#define UNESCAPE_HEX 0x04
|
|
|
|
#define UNESCAPE_SPECIAL 0x08
|
|
|
|
#define UNESCAPE_ANY \
|
|
|
|
(UNESCAPE_SPACE | UNESCAPE_OCTAL | UNESCAPE_HEX | UNESCAPE_SPECIAL)
|
|
|
|
|
|
|
|
int string_unescape(char *src, char *dst, size_t size, unsigned int flags);
|
|
|
|
|
|
|
|
static inline int string_unescape_inplace(char *buf, unsigned int flags)
|
|
|
|
{
|
|
|
|
return string_unescape(buf, buf, 0, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int string_unescape_any(char *src, char *dst, size_t size)
|
|
|
|
{
|
|
|
|
return string_unescape(src, dst, size, UNESCAPE_ANY);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int string_unescape_any_inplace(char *buf)
|
|
|
|
{
|
|
|
|
return string_unescape_any(buf, buf, 0);
|
|
|
|
}
|
|
|
|
|
2014-10-14 05:55:16 +07:00
|
|
|
#define ESCAPE_SPACE 0x01
|
|
|
|
#define ESCAPE_SPECIAL 0x02
|
|
|
|
#define ESCAPE_NULL 0x04
|
|
|
|
#define ESCAPE_OCTAL 0x08
|
|
|
|
#define ESCAPE_ANY \
|
|
|
|
(ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_SPECIAL | ESCAPE_NULL)
|
|
|
|
#define ESCAPE_NP 0x10
|
|
|
|
#define ESCAPE_ANY_NP (ESCAPE_ANY | ESCAPE_NP)
|
|
|
|
#define ESCAPE_HEX 0x20
|
|
|
|
|
lib/string_helpers.c: change semantics of string_escape_mem
The current semantics of string_escape_mem are inadequate for one of its
current users, vsnprintf(). If that is to honour its contract, it must
know how much space would be needed for the entire escaped buffer, and
string_escape_mem provides no way of obtaining that (short of allocating a
large enough buffer (~4 times input string) to let it play with, and
that's definitely a big no-no inside vsnprintf).
So change the semantics for string_escape_mem to be more snprintf-like:
Return the size of the output that would be generated if the destination
buffer was big enough, but of course still only write to the part of dst
it is allowed to, and (contrary to snprintf) don't do '\0'-termination.
It is then up to the caller to detect whether output was truncated and to
append a '\0' if desired. Also, we must output partial escape sequences,
otherwise a call such as snprintf(buf, 3, "%1pE", "\123") would cause
printf to write a \0 to buf[2] but leaving buf[0] and buf[1] with whatever
they previously contained.
This also fixes a bug in the escaped_string() helper function, which used
to unconditionally pass a length of "end-buf" to string_escape_mem();
since the latter doesn't check osz for being insanely large, it would
happily write to dst. For example, kasprintf(GFP_KERNEL, "something and
then %pE", ...); is an easy way to trigger an oops.
In test-string_helpers.c, the -ENOMEM test is replaced with testing for
getting the expected return value even if the buffer is too small. We
also ensure that nothing is written (by relying on a NULL pointer deref)
if the output size is 0 by passing NULL - this has to work for
kasprintf("%pE") to work.
In net/sunrpc/cache.c, I think qword_add still has the same semantics.
Someone should definitely double-check this.
In fs/proc/array.c, I made the minimum possible change, but longer-term it
should stop poking around in seq_file internals.
[andriy.shevchenko@linux.intel.com: simplify qword_add]
[andriy.shevchenko@linux.intel.com: add missed curly braces]
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-04-16 06:17:28 +07:00
|
|
|
int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz,
|
2015-09-10 05:37:16 +07:00
|
|
|
unsigned int flags, const char *only);
|
2014-10-14 05:55:16 +07:00
|
|
|
|
|
|
|
static inline int string_escape_mem_any_np(const char *src, size_t isz,
|
2015-09-10 05:37:16 +07:00
|
|
|
char *dst, size_t osz, const char *only)
|
2014-10-14 05:55:16 +07:00
|
|
|
{
|
2015-09-10 05:37:16 +07:00
|
|
|
return string_escape_mem(src, isz, dst, osz, ESCAPE_ANY_NP, only);
|
2014-10-14 05:55:16 +07:00
|
|
|
}
|
|
|
|
|
lib/string_helpers.c: change semantics of string_escape_mem
The current semantics of string_escape_mem are inadequate for one of its
current users, vsnprintf(). If that is to honour its contract, it must
know how much space would be needed for the entire escaped buffer, and
string_escape_mem provides no way of obtaining that (short of allocating a
large enough buffer (~4 times input string) to let it play with, and
that's definitely a big no-no inside vsnprintf).
So change the semantics for string_escape_mem to be more snprintf-like:
Return the size of the output that would be generated if the destination
buffer was big enough, but of course still only write to the part of dst
it is allowed to, and (contrary to snprintf) don't do '\0'-termination.
It is then up to the caller to detect whether output was truncated and to
append a '\0' if desired. Also, we must output partial escape sequences,
otherwise a call such as snprintf(buf, 3, "%1pE", "\123") would cause
printf to write a \0 to buf[2] but leaving buf[0] and buf[1] with whatever
they previously contained.
This also fixes a bug in the escaped_string() helper function, which used
to unconditionally pass a length of "end-buf" to string_escape_mem();
since the latter doesn't check osz for being insanely large, it would
happily write to dst. For example, kasprintf(GFP_KERNEL, "something and
then %pE", ...); is an easy way to trigger an oops.
In test-string_helpers.c, the -ENOMEM test is replaced with testing for
getting the expected return value even if the buffer is too small. We
also ensure that nothing is written (by relying on a NULL pointer deref)
if the output size is 0 by passing NULL - this has to work for
kasprintf("%pE") to work.
In net/sunrpc/cache.c, I think qword_add still has the same semantics.
Someone should definitely double-check this.
In fs/proc/array.c, I made the minimum possible change, but longer-term it
should stop poking around in seq_file internals.
[andriy.shevchenko@linux.intel.com: simplify qword_add]
[andriy.shevchenko@linux.intel.com: add missed curly braces]
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-04-16 06:17:28 +07:00
|
|
|
static inline int string_escape_str(const char *src, char *dst, size_t sz,
|
2015-09-10 05:37:16 +07:00
|
|
|
unsigned int flags, const char *only)
|
2014-10-14 05:55:16 +07:00
|
|
|
{
|
2015-09-10 05:37:16 +07:00
|
|
|
return string_escape_mem(src, strlen(src), dst, sz, flags, only);
|
2014-10-14 05:55:16 +07:00
|
|
|
}
|
|
|
|
|
lib/string_helpers.c: change semantics of string_escape_mem
The current semantics of string_escape_mem are inadequate for one of its
current users, vsnprintf(). If that is to honour its contract, it must
know how much space would be needed for the entire escaped buffer, and
string_escape_mem provides no way of obtaining that (short of allocating a
large enough buffer (~4 times input string) to let it play with, and
that's definitely a big no-no inside vsnprintf).
So change the semantics for string_escape_mem to be more snprintf-like:
Return the size of the output that would be generated if the destination
buffer was big enough, but of course still only write to the part of dst
it is allowed to, and (contrary to snprintf) don't do '\0'-termination.
It is then up to the caller to detect whether output was truncated and to
append a '\0' if desired. Also, we must output partial escape sequences,
otherwise a call such as snprintf(buf, 3, "%1pE", "\123") would cause
printf to write a \0 to buf[2] but leaving buf[0] and buf[1] with whatever
they previously contained.
This also fixes a bug in the escaped_string() helper function, which used
to unconditionally pass a length of "end-buf" to string_escape_mem();
since the latter doesn't check osz for being insanely large, it would
happily write to dst. For example, kasprintf(GFP_KERNEL, "something and
then %pE", ...); is an easy way to trigger an oops.
In test-string_helpers.c, the -ENOMEM test is replaced with testing for
getting the expected return value even if the buffer is too small. We
also ensure that nothing is written (by relying on a NULL pointer deref)
if the output size is 0 by passing NULL - this has to work for
kasprintf("%pE") to work.
In net/sunrpc/cache.c, I think qword_add still has the same semantics.
Someone should definitely double-check this.
In fs/proc/array.c, I made the minimum possible change, but longer-term it
should stop poking around in seq_file internals.
[andriy.shevchenko@linux.intel.com: simplify qword_add]
[andriy.shevchenko@linux.intel.com: add missed curly braces]
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-04-16 06:17:28 +07:00
|
|
|
static inline int string_escape_str_any_np(const char *src, char *dst,
|
2015-09-10 05:37:16 +07:00
|
|
|
size_t sz, const char *only)
|
2014-10-14 05:55:16 +07:00
|
|
|
{
|
2015-09-10 05:37:16 +07:00
|
|
|
return string_escape_str(src, dst, sz, ESCAPE_ANY_NP, only);
|
2014-10-14 05:55:16 +07:00
|
|
|
}
|
|
|
|
|
2008-08-31 22:13:54 +07:00
|
|
|
#endif
|