mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 21:24:08 +08:00
Merge branch 'akpm' (patches from Andrew)
Merge misc fixes from Andrew Morton: "11 fixes" * emailed patches form Andrew Morton <akpm@linux-foundation.org>: reiserfs: fix buffer overflow with long warning messages checkpatch: fix duplicate invalid vsprintf pointer extension '%p<foo>' messages mm: do not bug_on on incorrect length in __mm_populate() mm/memblock.c: do not complain about top-down allocations for !MEMORY_HOTREMOVE fs, elf: make sure to page align bss in load_elf_library x86/purgatory: add missing FORCE to Makefile target net/9p/client.c: put refcount of trans_mod in error case in parse_opts() mm: allow arch to supply p??_free_tlb functions autofs: fix slab out of bounds read in getname_kernel() fs/proc/task_mmu.c: fix Locked field in /proc/pid/smaps* mm: do not drop unused pages when userfaultd is running
This commit is contained in:
commit
f353078f02
@ -6,7 +6,7 @@ purgatory-y := purgatory.o stack.o setup-x86_$(BITS).o sha256.o entry64.o string
|
||||
targets += $(purgatory-y)
|
||||
PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
|
||||
|
||||
$(obj)/sha256.o: $(srctree)/lib/sha256.c
|
||||
$(obj)/sha256.o: $(srctree)/lib/sha256.c FORCE
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
|
||||
LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib -z nodefaultlib
|
||||
|
@ -135,6 +135,15 @@ static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
|
||||
cmd);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
unsigned int inr = _IOC_NR(cmd);
|
||||
|
||||
if (inr == AUTOFS_DEV_IOCTL_OPENMOUNT_CMD ||
|
||||
inr == AUTOFS_DEV_IOCTL_REQUESTER_CMD ||
|
||||
inr == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
err = 0;
|
||||
@ -271,7 +280,8 @@ static int autofs_dev_ioctl_openmount(struct file *fp,
|
||||
dev_t devid;
|
||||
int err, fd;
|
||||
|
||||
/* param->path has already been checked */
|
||||
/* param->path has been checked in validate_dev_ioctl() */
|
||||
|
||||
if (!param->openmount.devid)
|
||||
return -EINVAL;
|
||||
|
||||
@ -433,10 +443,7 @@ static int autofs_dev_ioctl_requester(struct file *fp,
|
||||
dev_t devid;
|
||||
int err = -ENOENT;
|
||||
|
||||
if (param->size <= AUTOFS_DEV_IOCTL_SIZE) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
/* param->path has been checked in validate_dev_ioctl() */
|
||||
|
||||
devid = sbi->sb->s_dev;
|
||||
|
||||
@ -521,10 +528,7 @@ static int autofs_dev_ioctl_ismountpoint(struct file *fp,
|
||||
unsigned int devid, magic;
|
||||
int err = -ENOENT;
|
||||
|
||||
if (param->size <= AUTOFS_DEV_IOCTL_SIZE) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
/* param->path has been checked in validate_dev_ioctl() */
|
||||
|
||||
name = param->path;
|
||||
type = param->ismountpoint.in.type;
|
||||
|
@ -1259,9 +1259,8 @@ static int load_elf_library(struct file *file)
|
||||
goto out_free_ph;
|
||||
}
|
||||
|
||||
len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr +
|
||||
ELF_MIN_ALIGN - 1);
|
||||
bss = eppnt->p_memsz + eppnt->p_vaddr;
|
||||
len = ELF_PAGEALIGN(eppnt->p_filesz + eppnt->p_vaddr);
|
||||
bss = ELF_PAGEALIGN(eppnt->p_memsz + eppnt->p_vaddr);
|
||||
if (bss > len) {
|
||||
error = vm_brk(len, bss - len);
|
||||
if (error)
|
||||
|
@ -831,7 +831,8 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
|
||||
SEQ_PUT_DEC(" kB\nSwap: ", mss->swap);
|
||||
SEQ_PUT_DEC(" kB\nSwapPss: ",
|
||||
mss->swap_pss >> PSS_SHIFT);
|
||||
SEQ_PUT_DEC(" kB\nLocked: ", mss->pss >> PSS_SHIFT);
|
||||
SEQ_PUT_DEC(" kB\nLocked: ",
|
||||
mss->pss_locked >> PSS_SHIFT);
|
||||
seq_puts(m, " kB\n");
|
||||
}
|
||||
if (!rollup_mode) {
|
||||
|
@ -76,83 +76,99 @@ static char *le_type(struct reiserfs_key *key)
|
||||
}
|
||||
|
||||
/* %k */
|
||||
static void sprintf_le_key(char *buf, struct reiserfs_key *key)
|
||||
static int scnprintf_le_key(char *buf, size_t size, struct reiserfs_key *key)
|
||||
{
|
||||
if (key)
|
||||
sprintf(buf, "[%d %d %s %s]", le32_to_cpu(key->k_dir_id),
|
||||
le32_to_cpu(key->k_objectid), le_offset(key),
|
||||
le_type(key));
|
||||
return scnprintf(buf, size, "[%d %d %s %s]",
|
||||
le32_to_cpu(key->k_dir_id),
|
||||
le32_to_cpu(key->k_objectid), le_offset(key),
|
||||
le_type(key));
|
||||
else
|
||||
sprintf(buf, "[NULL]");
|
||||
return scnprintf(buf, size, "[NULL]");
|
||||
}
|
||||
|
||||
/* %K */
|
||||
static void sprintf_cpu_key(char *buf, struct cpu_key *key)
|
||||
static int scnprintf_cpu_key(char *buf, size_t size, struct cpu_key *key)
|
||||
{
|
||||
if (key)
|
||||
sprintf(buf, "[%d %d %s %s]", key->on_disk_key.k_dir_id,
|
||||
key->on_disk_key.k_objectid, reiserfs_cpu_offset(key),
|
||||
cpu_type(key));
|
||||
return scnprintf(buf, size, "[%d %d %s %s]",
|
||||
key->on_disk_key.k_dir_id,
|
||||
key->on_disk_key.k_objectid,
|
||||
reiserfs_cpu_offset(key), cpu_type(key));
|
||||
else
|
||||
sprintf(buf, "[NULL]");
|
||||
return scnprintf(buf, size, "[NULL]");
|
||||
}
|
||||
|
||||
static void sprintf_de_head(char *buf, struct reiserfs_de_head *deh)
|
||||
static int scnprintf_de_head(char *buf, size_t size,
|
||||
struct reiserfs_de_head *deh)
|
||||
{
|
||||
if (deh)
|
||||
sprintf(buf,
|
||||
"[offset=%d dir_id=%d objectid=%d location=%d state=%04x]",
|
||||
deh_offset(deh), deh_dir_id(deh), deh_objectid(deh),
|
||||
deh_location(deh), deh_state(deh));
|
||||
return scnprintf(buf, size,
|
||||
"[offset=%d dir_id=%d objectid=%d location=%d state=%04x]",
|
||||
deh_offset(deh), deh_dir_id(deh),
|
||||
deh_objectid(deh), deh_location(deh),
|
||||
deh_state(deh));
|
||||
else
|
||||
sprintf(buf, "[NULL]");
|
||||
return scnprintf(buf, size, "[NULL]");
|
||||
|
||||
}
|
||||
|
||||
static void sprintf_item_head(char *buf, struct item_head *ih)
|
||||
static int scnprintf_item_head(char *buf, size_t size, struct item_head *ih)
|
||||
{
|
||||
if (ih) {
|
||||
strcpy(buf,
|
||||
(ih_version(ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*");
|
||||
sprintf_le_key(buf + strlen(buf), &(ih->ih_key));
|
||||
sprintf(buf + strlen(buf), ", item_len %d, item_location %d, "
|
||||
"free_space(entry_count) %d",
|
||||
ih_item_len(ih), ih_location(ih), ih_free_space(ih));
|
||||
char *p = buf;
|
||||
char * const end = buf + size;
|
||||
|
||||
p += scnprintf(p, end - p, "%s",
|
||||
(ih_version(ih) == KEY_FORMAT_3_6) ?
|
||||
"*3.6* " : "*3.5*");
|
||||
|
||||
p += scnprintf_le_key(p, end - p, &ih->ih_key);
|
||||
|
||||
p += scnprintf(p, end - p,
|
||||
", item_len %d, item_location %d, free_space(entry_count) %d",
|
||||
ih_item_len(ih), ih_location(ih),
|
||||
ih_free_space(ih));
|
||||
return p - buf;
|
||||
} else
|
||||
sprintf(buf, "[NULL]");
|
||||
return scnprintf(buf, size, "[NULL]");
|
||||
}
|
||||
|
||||
static void sprintf_direntry(char *buf, struct reiserfs_dir_entry *de)
|
||||
static int scnprintf_direntry(char *buf, size_t size,
|
||||
struct reiserfs_dir_entry *de)
|
||||
{
|
||||
char name[20];
|
||||
|
||||
memcpy(name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen);
|
||||
name[de->de_namelen > 19 ? 19 : de->de_namelen] = 0;
|
||||
sprintf(buf, "\"%s\"==>[%d %d]", name, de->de_dir_id, de->de_objectid);
|
||||
return scnprintf(buf, size, "\"%s\"==>[%d %d]",
|
||||
name, de->de_dir_id, de->de_objectid);
|
||||
}
|
||||
|
||||
static void sprintf_block_head(char *buf, struct buffer_head *bh)
|
||||
static int scnprintf_block_head(char *buf, size_t size, struct buffer_head *bh)
|
||||
{
|
||||
sprintf(buf, "level=%d, nr_items=%d, free_space=%d rdkey ",
|
||||
B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh));
|
||||
return scnprintf(buf, size,
|
||||
"level=%d, nr_items=%d, free_space=%d rdkey ",
|
||||
B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh));
|
||||
}
|
||||
|
||||
static void sprintf_buffer_head(char *buf, struct buffer_head *bh)
|
||||
static int scnprintf_buffer_head(char *buf, size_t size, struct buffer_head *bh)
|
||||
{
|
||||
sprintf(buf,
|
||||
"dev %pg, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
|
||||
bh->b_bdev, bh->b_size,
|
||||
(unsigned long long)bh->b_blocknr, atomic_read(&(bh->b_count)),
|
||||
bh->b_state, bh->b_page,
|
||||
buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE",
|
||||
buffer_dirty(bh) ? "DIRTY" : "CLEAN",
|
||||
buffer_locked(bh) ? "LOCKED" : "UNLOCKED");
|
||||
return scnprintf(buf, size,
|
||||
"dev %pg, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
|
||||
bh->b_bdev, bh->b_size,
|
||||
(unsigned long long)bh->b_blocknr,
|
||||
atomic_read(&(bh->b_count)),
|
||||
bh->b_state, bh->b_page,
|
||||
buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE",
|
||||
buffer_dirty(bh) ? "DIRTY" : "CLEAN",
|
||||
buffer_locked(bh) ? "LOCKED" : "UNLOCKED");
|
||||
}
|
||||
|
||||
static void sprintf_disk_child(char *buf, struct disk_child *dc)
|
||||
static int scnprintf_disk_child(char *buf, size_t size, struct disk_child *dc)
|
||||
{
|
||||
sprintf(buf, "[dc_number=%d, dc_size=%u]", dc_block_number(dc),
|
||||
dc_size(dc));
|
||||
return scnprintf(buf, size, "[dc_number=%d, dc_size=%u]",
|
||||
dc_block_number(dc), dc_size(dc));
|
||||
}
|
||||
|
||||
static char *is_there_reiserfs_struct(char *fmt, int *what)
|
||||
@ -189,55 +205,60 @@ static void prepare_error_buf(const char *fmt, va_list args)
|
||||
char *fmt1 = fmt_buf;
|
||||
char *k;
|
||||
char *p = error_buf;
|
||||
char * const end = &error_buf[sizeof(error_buf)];
|
||||
int what;
|
||||
|
||||
spin_lock(&error_lock);
|
||||
|
||||
strcpy(fmt1, fmt);
|
||||
if (WARN_ON(strscpy(fmt_buf, fmt, sizeof(fmt_buf)) < 0)) {
|
||||
strscpy(error_buf, "format string too long", end - error_buf);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
while ((k = is_there_reiserfs_struct(fmt1, &what)) != NULL) {
|
||||
*k = 0;
|
||||
|
||||
p += vsprintf(p, fmt1, args);
|
||||
p += vscnprintf(p, end - p, fmt1, args);
|
||||
|
||||
switch (what) {
|
||||
case 'k':
|
||||
sprintf_le_key(p, va_arg(args, struct reiserfs_key *));
|
||||
p += scnprintf_le_key(p, end - p,
|
||||
va_arg(args, struct reiserfs_key *));
|
||||
break;
|
||||
case 'K':
|
||||
sprintf_cpu_key(p, va_arg(args, struct cpu_key *));
|
||||
p += scnprintf_cpu_key(p, end - p,
|
||||
va_arg(args, struct cpu_key *));
|
||||
break;
|
||||
case 'h':
|
||||
sprintf_item_head(p, va_arg(args, struct item_head *));
|
||||
p += scnprintf_item_head(p, end - p,
|
||||
va_arg(args, struct item_head *));
|
||||
break;
|
||||
case 't':
|
||||
sprintf_direntry(p,
|
||||
va_arg(args,
|
||||
struct reiserfs_dir_entry *));
|
||||
p += scnprintf_direntry(p, end - p,
|
||||
va_arg(args, struct reiserfs_dir_entry *));
|
||||
break;
|
||||
case 'y':
|
||||
sprintf_disk_child(p,
|
||||
va_arg(args, struct disk_child *));
|
||||
p += scnprintf_disk_child(p, end - p,
|
||||
va_arg(args, struct disk_child *));
|
||||
break;
|
||||
case 'z':
|
||||
sprintf_block_head(p,
|
||||
va_arg(args, struct buffer_head *));
|
||||
p += scnprintf_block_head(p, end - p,
|
||||
va_arg(args, struct buffer_head *));
|
||||
break;
|
||||
case 'b':
|
||||
sprintf_buffer_head(p,
|
||||
va_arg(args, struct buffer_head *));
|
||||
p += scnprintf_buffer_head(p, end - p,
|
||||
va_arg(args, struct buffer_head *));
|
||||
break;
|
||||
case 'a':
|
||||
sprintf_de_head(p,
|
||||
va_arg(args,
|
||||
struct reiserfs_de_head *));
|
||||
p += scnprintf_de_head(p, end - p,
|
||||
va_arg(args, struct reiserfs_de_head *));
|
||||
break;
|
||||
}
|
||||
|
||||
p += strlen(p);
|
||||
fmt1 = k + 2;
|
||||
}
|
||||
vsprintf(p, fmt1, args);
|
||||
p += vscnprintf(p, end - p, fmt1, args);
|
||||
out_unlock:
|
||||
spin_unlock(&error_lock);
|
||||
|
||||
}
|
||||
|
@ -265,33 +265,41 @@ static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
|
||||
* For now w.r.t page table cache, mark the range_size as PAGE_SIZE
|
||||
*/
|
||||
|
||||
#ifndef pte_free_tlb
|
||||
#define pte_free_tlb(tlb, ptep, address) \
|
||||
do { \
|
||||
__tlb_adjust_range(tlb, address, PAGE_SIZE); \
|
||||
__pte_free_tlb(tlb, ptep, address); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef pmd_free_tlb
|
||||
#define pmd_free_tlb(tlb, pmdp, address) \
|
||||
do { \
|
||||
__tlb_adjust_range(tlb, address, PAGE_SIZE); \
|
||||
__pmd_free_tlb(tlb, pmdp, address); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef __ARCH_HAS_4LEVEL_HACK
|
||||
#ifndef pud_free_tlb
|
||||
#define pud_free_tlb(tlb, pudp, address) \
|
||||
do { \
|
||||
__tlb_adjust_range(tlb, address, PAGE_SIZE); \
|
||||
__pud_free_tlb(tlb, pudp, address); \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __ARCH_HAS_5LEVEL_HACK
|
||||
#ifndef p4d_free_tlb
|
||||
#define p4d_free_tlb(tlb, pudp, address) \
|
||||
do { \
|
||||
__tlb_adjust_range(tlb, address, PAGE_SIZE); \
|
||||
__p4d_free_tlb(tlb, pudp, address); \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define tlb_migrate_finish(mm) do {} while (0)
|
||||
|
||||
|
2
mm/gup.c
2
mm/gup.c
@ -1238,8 +1238,6 @@ int __mm_populate(unsigned long start, unsigned long len, int ignore_errors)
|
||||
int locked = 0;
|
||||
long ret = 0;
|
||||
|
||||
VM_BUG_ON(start & ~PAGE_MASK);
|
||||
VM_BUG_ON(len != PAGE_ALIGN(len));
|
||||
end = start + len;
|
||||
|
||||
for (nstart = start; nstart < end; nstart = nend) {
|
||||
|
@ -227,7 +227,8 @@ phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t size,
|
||||
* so we use WARN_ONCE() here to see the stack trace if
|
||||
* fail happens.
|
||||
*/
|
||||
WARN_ONCE(1, "memblock: bottom-up allocation failed, memory hotunplug may be affected\n");
|
||||
WARN_ONCE(IS_ENABLED(CONFIG_MEMORY_HOTREMOVE),
|
||||
"memblock: bottom-up allocation failed, memory hotremove may be affected\n");
|
||||
}
|
||||
|
||||
return __memblock_find_range_top_down(start, end, size, align, nid,
|
||||
|
29
mm/mmap.c
29
mm/mmap.c
@ -186,8 +186,8 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
|
||||
return next;
|
||||
}
|
||||
|
||||
static int do_brk(unsigned long addr, unsigned long len, struct list_head *uf);
|
||||
|
||||
static int do_brk_flags(unsigned long addr, unsigned long request, unsigned long flags,
|
||||
struct list_head *uf);
|
||||
SYSCALL_DEFINE1(brk, unsigned long, brk)
|
||||
{
|
||||
unsigned long retval;
|
||||
@ -245,7 +245,7 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
|
||||
goto out;
|
||||
|
||||
/* Ok, looks good - let it rip. */
|
||||
if (do_brk(oldbrk, newbrk-oldbrk, &uf) < 0)
|
||||
if (do_brk_flags(oldbrk, newbrk-oldbrk, 0, &uf) < 0)
|
||||
goto out;
|
||||
|
||||
set_brk:
|
||||
@ -2929,21 +2929,14 @@ static inline void verify_mm_writelocked(struct mm_struct *mm)
|
||||
* anonymous maps. eventually we may be able to do some
|
||||
* brk-specific accounting here.
|
||||
*/
|
||||
static int do_brk_flags(unsigned long addr, unsigned long request, unsigned long flags, struct list_head *uf)
|
||||
static int do_brk_flags(unsigned long addr, unsigned long len, unsigned long flags, struct list_head *uf)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
struct vm_area_struct *vma, *prev;
|
||||
unsigned long len;
|
||||
struct rb_node **rb_link, *rb_parent;
|
||||
pgoff_t pgoff = addr >> PAGE_SHIFT;
|
||||
int error;
|
||||
|
||||
len = PAGE_ALIGN(request);
|
||||
if (len < request)
|
||||
return -ENOMEM;
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
/* Until we need other flags, refuse anything except VM_EXEC. */
|
||||
if ((flags & (~VM_EXEC)) != 0)
|
||||
return -EINVAL;
|
||||
@ -3015,18 +3008,20 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_brk(unsigned long addr, unsigned long len, struct list_head *uf)
|
||||
{
|
||||
return do_brk_flags(addr, len, 0, uf);
|
||||
}
|
||||
|
||||
int vm_brk_flags(unsigned long addr, unsigned long len, unsigned long flags)
|
||||
int vm_brk_flags(unsigned long addr, unsigned long request, unsigned long flags)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
unsigned long len;
|
||||
int ret;
|
||||
bool populate;
|
||||
LIST_HEAD(uf);
|
||||
|
||||
len = PAGE_ALIGN(request);
|
||||
if (len < request)
|
||||
return -ENOMEM;
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
if (down_write_killable(&mm->mmap_sem))
|
||||
return -EINTR;
|
||||
|
||||
|
@ -64,6 +64,7 @@
|
||||
#include <linux/backing-dev.h>
|
||||
#include <linux/page_idle.h>
|
||||
#include <linux/memremap.h>
|
||||
#include <linux/userfaultfd_k.h>
|
||||
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
@ -1481,11 +1482,16 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
|
||||
set_pte_at(mm, address, pvmw.pte, pteval);
|
||||
}
|
||||
|
||||
} else if (pte_unused(pteval)) {
|
||||
} else if (pte_unused(pteval) && !userfaultfd_armed(vma)) {
|
||||
/*
|
||||
* The guest indicated that the page content is of no
|
||||
* interest anymore. Simply discard the pte, vmscan
|
||||
* will take care of the rest.
|
||||
* A future reference will then fault in a new zero
|
||||
* page. When userfaultfd is active, we must not drop
|
||||
* this page though, as its main user (postcopy
|
||||
* migration) will not expect userfaults on already
|
||||
* copied pages.
|
||||
*/
|
||||
dec_mm_counter(mm, mm_counter(page));
|
||||
/* We have to invalidate as we cleared the pte */
|
||||
|
@ -225,7 +225,8 @@ static int parse_opts(char *opts, struct p9_client *clnt)
|
||||
}
|
||||
|
||||
free_and_return:
|
||||
v9fs_put_trans(clnt->trans_mod);
|
||||
if (ret)
|
||||
v9fs_put_trans(clnt->trans_mod);
|
||||
kfree(tmp_options);
|
||||
return ret;
|
||||
}
|
||||
|
@ -5813,14 +5813,14 @@ sub process {
|
||||
defined $stat &&
|
||||
$stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
|
||||
$1 !~ /^_*volatile_*$/) {
|
||||
my $specifier;
|
||||
my $extension;
|
||||
my $bad_specifier = "";
|
||||
my $stat_real;
|
||||
|
||||
my $lc = $stat =~ tr@\n@@;
|
||||
$lc = $lc + $linenr;
|
||||
for (my $count = $linenr; $count <= $lc; $count++) {
|
||||
my $specifier;
|
||||
my $extension;
|
||||
my $bad_specifier = "";
|
||||
my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
|
||||
$fmt =~ s/%%//g;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user